package com.example.spring.proxy;

import org.springframework.beans.factory.FactoryBean;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;

import java.lang.reflect.Proxy;
import java.util.Objects;

/**
 * @author YangZhen
 * @date 2022/5/28 15:11
 * @since 1.0.0
 */
public class OpenapiFactoryBean<T> implements FactoryBean<T>, ApplicationListener<ApplicationEvent> {

    /**
     * 原始 bean class
     */
    private Class<T> sourceClass;

    /**
     * 代理 bean
     */
    private T proxyBean;

    public OpenapiFactoryBean(Class<T> sourceClass) {
        this.sourceClass = sourceClass;
    }

    @Override
    public T getObject() throws Exception {
        if (Objects.isNull(proxyBean)) {
            // 初始化 open api
            proxyBean = (T) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class[]{sourceClass}, new JdkDynamicAopProxy());
        }
        return proxyBean;
    }

    @Override
    public Class<T> getObjectType() {
        return this.sourceClass;
    }

    /**
     * ContextRefreshedEvent 后初始化 open api
     *
     * @param event
     */
    @Override
    public void onApplicationEvent(ApplicationEvent event) {
        if (event instanceof ContextRefreshedEvent) {
            if (Objects.isNull(proxyBean)) {
                proxyBean = (T) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class[]{sourceClass}, new JdkDynamicAopProxy());
            }
        }
    }
}
